<template><div><h2 id="事件-events" tabindex="-1"><a class="header-anchor" href="#事件-events"><span>事件（Events）</span></a></h2>
<p>事件，可以将自定义代码“注入”到现有代码中的特定执行点。附加自定义代码到某个事件，当这个事件被触发时，这些代码就会自动执行。例如，邮件程序对象成功发出消息时可触发 <code v-pre>messageSent</code> 事件。如想追踪成功发送的消息，可以附加相应追踪代码到 <code v-pre>messageSent</code> 事件。</p>
<p>Yii 引入了名为 <code v-pre>yii\base\Component</code> 的基类以支持事件，如果一个类需要触发事件就应该继承它或其子类。</p>
<h2 id="事件处理器" tabindex="-1"><a class="header-anchor" href="#事件处理器"><span>事件处理器</span></a></h2>
<p>事件处理器是一个 <a href="https://www.php.net/manual/zh/language.types.callable.php" target="_blank" rel="noopener noreferrer">PHP 回调函数</a>，当它所附加到的事件被触发时它就会执行，它可以使用以下回调函数之一：</p>
<ul>
<li>字符串形式指定的 PHP 全局函数，如 <code v-pre>'trim'</code>；</li>
<li>对象名和方法名数组形式指定的对象方法，如 <code v-pre>[$object, $method]</code>；</li>
<li>类名和方法名数组形式指定的静态类方法，如 <code v-pre>[$class, $method]</code>；</li>
<li>匿名函数，如 <code v-pre>function ($event) { ... }</code>。</li>
</ul>
<p>事件处理器的格式是：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// $event 是 yii\base\Event 或其子类的对象</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>通过 <code v-pre>$event</code> 参数，事件处理器就获得了以下有关事件的信息：</p>
<ul>
<li>[[yii\base\Event::name]]：事件名</li>
<li>[[yii\base\Event::sender]]：事件发送者，调用 <code v-pre>trigger()</code> 方法的对象</li>
<li>[[yii\base\Event::data]]：自定义数据，附加事件处理器时传入的数据，默认为空，后文详述</li>
</ul>
<h2 id="附加事件处理器" tabindex="-1"><a class="header-anchor" href="#附加事件处理器"><span>附加事件处理器</span></a></h2>
<p>调用 [[yii\base\Component::on()]] 方法来附加处理器到事件上。如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$foo</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Foo</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 处理器是全局函数</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'function_name'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 处理器是对象方法</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token variable">$object</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'methodName'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 处理器是静态类方法</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'app\components\Bar'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'methodName'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 处理器是匿名函数</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">//事件处理逻辑</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你也可以通过 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/concept-configurations.md" target="_blank" rel="noopener noreferrer">配置</a> 附加事件处理器。请参考 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/concept-configurations.md#configuration-format" target="_blank" rel="noopener noreferrer">配置的格式</a> 小节了解更多。</p>
<p>附加事件处理器，可以提供额外数据作为 [[yii\base\Component::on()]] 方法的第三个参数。 数据在事件被触发和处理器被调用时，能被处理器使用。如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// 当事件被触发时以下代码显示 "abc"</span></span>
<span class="line"><span class="token comment">// 因为 $event->data 包括被传递到 "on" 方法的数据</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'function_name'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'abc'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">function</span> <span class="token function-definition function">function_name</span><span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">echo</span> <span class="token variable">$event</span><span class="token operator">-></span><span class="token property">data</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="事件处理器顺序" tabindex="-1"><a class="header-anchor" href="#事件处理器顺序"><span>事件处理器顺序</span></a></h2>
<p>可以附加一个或多个处理器到一个事件。当事件被触发，已附加的处理器将按附加次序依次调用。如果某个处理器需要停止其后的处理器调用，可以设置 <code v-pre>$event</code> 参数的 [[yii\base\Event::handled]] 属性为真，如下：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token variable">$event</span><span class="token operator">-></span><span class="token property">handled</span> <span class="token operator">=</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>默认新附加的事件处理器排在已存在处理器队列的最后。因此，这个处理器将在事件被触发时最后一个调用。在处理器队列最前面插入新处理器将使该处理器最先调用，可以传递第四个参数 <code v-pre>$append</code> 为假并调用 [[yii\base\Component::on()]] 方法实现：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 这个处理器将被插入到处理器队列的第一位...</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token variable">$data</span><span class="token punctuation">,</span> <span class="token constant boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="触发事件" tabindex="-1"><a class="header-anchor" href="#触发事件"><span>触发事件</span></a></h2>
<p>事件通过调用 [[yii\base\Component::trigger()]] 方法触发，此方法须传递 <em>事件名</em>，还可以传递一个事件对象，用来传递参数到事件处理器。如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">namespace</span> <span class="token package">app<span class="token punctuation">\</span>components</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>Component</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>Event</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Foo</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">const</span> <span class="token constant">EVENT_HELLO</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'hello'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token keyword static-context">self</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>以上代码当调用 <code v-pre>bar()</code> ，它将触发名为 <code v-pre>hello</code> 的事件。</p>
<blockquote>
<p>Tip: 推荐使用类常量来表示事件名。上例中，常量 <code v-pre>EVENT_HELLO</code> 用来表示 <code v-pre>hello</code> 。这有两个好处。第一，它可以防止拼写错误并支持 IDE 的自动完成。第二，只要简单检查常量声明就能了解一个类支持哪些事件。</p>
</blockquote>
<p>有时想要在触发事件时同时传递一些额外信息到事件处理器。例如，邮件程序要传递消息信息到 <code v-pre>messageSent</code> 事件的处理器以便处理器了解哪些消息被发送了。为此，可以提供一个事件对象作为 [[yii\base\Component::trigger()]] 方法的第二个参数。这个事件对象必须是 [[yii\base\Event]] 类或其子类的实例。如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">namespace</span> <span class="token package">app<span class="token punctuation">\</span>components</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>Component</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>Event</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">MessageEvent</span> <span class="token keyword">extends</span> <span class="token class-name">Event</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token variable">$message</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Mailer</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">const</span> <span class="token constant">EVENT_MESSAGE_SENT</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'messageSent'</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">send</span><span class="token punctuation">(</span><span class="token variable">$message</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// ...发送 $message 的逻辑...</span></span>
<span class="line"></span>
<span class="line">        <span class="token variable">$event</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MessageEvent</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token variable">$event</span><span class="token operator">-></span><span class="token property">message</span> <span class="token operator">=</span> <span class="token variable">$message</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token keyword static-context">self</span><span class="token operator">::</span><span class="token constant">EVENT_MESSAGE_SENT</span><span class="token punctuation">,</span> <span class="token variable">$event</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>当 [[yii\base\Component::trigger()]] 方法被调用时，它将调用所有附加到命名事件（trigger 方法第一个参数）的事件处理器。</p>
<h2 id="移除事件处理器" tabindex="-1"><a class="header-anchor" href="#移除事件处理器"><span>移除事件处理器</span></a></h2>
<p>从事件移除处理器，调用 [[yii\base\Component::off()]] 方法。如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// 处理器是全局函数</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">off</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'function_name'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 处理器是对象方法</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">off</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token variable">$object</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'methodName'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 处理器是静态类方法</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">off</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'app\components\Bar'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'methodName'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 处理器是匿名函数</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">off</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token variable">$anonymousFunction</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>注意当匿名函数附加到事件后一般不要尝试移除匿名函数，除非你在某处存储了它。以上示例中，假设匿名函数存储为变量 <code v-pre>$anonymousFunction</code> 。</p>
<p>移除事件的全部处理器，简单调用 [[yii\base\Component::off()]] 即可，不需要第二个参数：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">off</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="类级别的事件处理器" tabindex="-1"><a class="header-anchor" href="#类级别的事件处理器"><span>类级别的事件处理器</span></a></h2>
<p>以上部分，我们叙述了在 <em>实例级别</em> 如何附加处理器到事件。有时想要一个类的 <em>所有</em> 实例而不是一个指定的实例都响应一个被触发的事件，并不是一个个附加事件处理器到每个实例，而是通过调用静态方法 [[yii\base\Event::on()]] 在 <em>类级别</em> 附加处理器。</p>
<p>例如，<a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/db-active-record.md" target="_blank" rel="noopener noreferrer">活动记录</a> 对象要在每次往数据库新增一条新记录时触发一个 [[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT]] 事件。要追踪每个 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/db-active-record.md" target="_blank" rel="noopener noreferrer">活动记录</a> 对象的新增记录完成情况，应如下写代码：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Yii</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>Event</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>db<span class="token punctuation">\</span>ActiveRecord</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token class-name static-context">ActiveRecord</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name static-context">ActiveRecord</span><span class="token operator">::</span><span class="token constant">EVENT_AFTER_INSERT</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token function">get_class</span><span class="token punctuation">(</span><span class="token variable">$event</span><span class="token operator">-></span><span class="token property">sender</span><span class="token punctuation">)</span> <span class="token operator">.</span> <span class="token string single-quoted-string">' is inserted'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>每当 [[yii\db\BaseActiveRecord]] 或其子类的实例触发 [[yii\db\BaseActiveRecord::EVENT_AFTER_INSERT]] 事件时，这个事件处理器都会执行。在这个处理器中，可以通过 <code v-pre>$event-&gt;sender</code> 获取触发事件的对象。</p>
<p>当对象触发事件时，它首先调用实例级别的处理器，然后才会调用类级别处理器。</p>
<p>可调用静态方法 [[yii\base\Event::trigger()]] 来触发一个 <em>类级别</em> 事件。类级别事件不与特定对象相关联。因此，它只会引起类级别事件处理器的调用。如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>Event</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token function">var_dump</span><span class="token punctuation">(</span><span class="token variable">$event</span><span class="token operator">-></span><span class="token property">sender</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 显示 "null"</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>注意这种情况下 <code v-pre>$event-&gt;sender</code> 指向触发事件的类名而不是对象实例。</p>
<blockquote>
<p>Note: 因为类级别的处理器响应类和其子类的所有实例触发的事件，必须谨慎使用，尤其是底层的基类，如 <code v-pre>yii\base\Object</code>。</p>
</blockquote>
<p>移除类级别的事件处理器只需调用 [[yii\base\Event::off()]]，如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// 移除 $handler</span></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">off</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">,</span> <span class="token variable">$handler</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 移除 Foo::EVENT_HELLO 事件的全部处理器</span></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">off</span><span class="token punctuation">(</span><span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name static-context">Foo</span><span class="token operator">::</span><span class="token constant">EVENT_HELLO</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="使用接口事件" tabindex="-1"><a class="header-anchor" href="#使用接口事件"><span>使用接口事件</span></a></h2>
<p>有更多的抽象方式来处理事件。你可以为特殊的事件创建一个独立的接口，然后在你需要的类中实现它。</p>
<p>例如，我们可以先创建下面这个接口:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">namespace</span> <span class="token package">app<span class="token punctuation">\</span>interfaces</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">interface</span> <span class="token class-name-definition class-name">DanceEventInterface</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">const</span> <span class="token constant">EVENT_DANCE</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'dance'</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>然后在两个类中实现:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Dog</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token keyword">implements</span> <span class="token class-name">DanceEventInterface</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">meetBuddy</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">echo</span> <span class="token string double-quoted-string">"Woof!"</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token class-name static-context">DanceEventInterface</span><span class="token operator">::</span><span class="token constant">EVENT_DANCE</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">Developer</span> <span class="token keyword">extends</span> <span class="token class-name">Component</span> <span class="token keyword">implements</span> <span class="token class-name">DanceEventInterface</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">testsPassed</span><span class="token punctuation">(</span><span class="token punctuation">)</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token keyword">echo</span> <span class="token string double-quoted-string">"Yay!"</span><span class="token punctuation">;</span></span>
<span class="line">        <span class="token variable">$this</span><span class="token operator">-></span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token class-name static-context">DanceEventInterface</span><span class="token operator">::</span><span class="token constant">EVENT_DANCE</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>要处理由这些类触发的 <code v-pre>EVENT_DANCE</code> ，调用 [[yii\base\Event::on()|Event::on()]] 并将接口类名作为第一个参数:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'app\interfaces\DanceEventInterface'</span><span class="token punctuation">,</span> <span class="token class-name static-context">DanceEventInterface</span><span class="token operator">::</span><span class="token constant">EVENT_DANCE</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token function">trace</span><span class="token punctuation">(</span><span class="token function">get_class</span><span class="token punctuation">(</span><span class="token variable">$event</span><span class="token operator">-></span><span class="token property">sender</span><span class="token punctuation">)</span> <span class="token operator">.</span> <span class="token string single-quoted-string">' just danced'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// Will log that Dog or Developer danced</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你可以在这些类中触发这个事件：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// Dog 类触发事件</span></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token class-name static-context">Dog</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name static-context">DanceEventInterface</span><span class="token operator">::</span><span class="token constant">EVENT_DANCE</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// Developer 类触发事件</span></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token class-name static-context">Developer</span><span class="token operator">::</span><span class="token keyword">class</span><span class="token punctuation">,</span> <span class="token class-name static-context">DanceEventInterface</span><span class="token operator">::</span><span class="token constant">EVENT_DANCE</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>但是请注意，你不能让所有实现这个接口的类都触发事件：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// 不会生效。实现此接口的类不会触发事件。</span></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'app\interfaces\DanceEventInterface'</span><span class="token punctuation">,</span> <span class="token class-name static-context">DanceEventInterface</span><span class="token operator">::</span><span class="token constant">EVENT_DANCE</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><p>调用 [[yii\base\Event::off()|Event::off()]] 移除事件处理器。例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token comment">// 移除 $handler</span></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">off</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'app\interfaces\DanceEventInterface'</span><span class="token punctuation">,</span> <span class="token class-name static-context">DanceEventInterface</span><span class="token operator">::</span><span class="token constant">EVENT_DANCE</span><span class="token punctuation">,</span> <span class="token variable">$handler</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 移除所有 `DanceEventInterface::EVENT_DANCE` 的处理器</span></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">off</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'app\interfaces\DanceEventInterface'</span><span class="token punctuation">,</span> <span class="token class-name static-context">DanceEventInterface</span><span class="token operator">::</span><span class="token constant">EVENT_DANCE</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="全局事件" tabindex="-1"><a class="header-anchor" href="#全局事件"><span>全局事件</span></a></h2>
<p>所谓 <em>全局事件</em> 实际上是一个基于以上叙述的事件机制的戏法。它需要一个全局可访问的单例，如 <a href="https://github.com/yiisoft/yii2/blob/master/docs/guide-zh-CN/structure-applications.md" target="_blank" rel="noopener noreferrer">应用</a> 实例。</p>
<p>事件触发者不调用其自身的 <code v-pre>trigger()</code> 方法，而是调用单例的 <code v-pre>trigger()</code> 方法来触发全局事件。类似地，事件处理器被附加到单例的事件。如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Yii</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>Event</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">app<span class="token punctuation">\</span>components<span class="token punctuation">\</span>Foo</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'bar'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">echo</span> <span class="token function">get_class</span><span class="token punctuation">(</span><span class="token variable">$event</span><span class="token operator">-></span><span class="token property">sender</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 显示 "app\components\Foo"</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token variable">$app</span><span class="token operator">-></span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'bar'</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Event</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'sender'</span> <span class="token operator">=></span> <span class="token keyword">new</span> <span class="token class-name">Foo</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>全局事件的一个好处是当附加处理器到一个对象要触发的事件时，不需要产生该对象。相反，处理器附加和事件触发都通过单例（如应用实例）完成。</p>
<p>然而，因为全局事件的命名空间由各方共享，应合理命名全局事件，如引入一些命名空间（例：”frontend.mail.sent”, “backend.mail.sent”）。</p>
<h2 id="通配符事件" tabindex="-1"><a class="header-anchor" href="#通配符事件"><span>通配符事件</span></a></h2>
<p>自 2.0.14 以来，您可以为多个匹配通配符模式的事件设置事件处理程序。 例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Yii</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$foo</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'foo.event.*'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 触发任何事件，该名称以 'foo.event.' 开头</span></span>
<span class="line">    <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'trigger event: '</span> <span class="token operator">.</span> <span class="token variable">$event</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>通配符模式也可以用于类级别的事件。例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>Event</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Yii</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'app\models\*'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'before*'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 触发命名空间 'app\models' 中的任何类的任何事件，名称以 'before' 开头。</span></span>
<span class="line">    <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'trigger event: '</span> <span class="token operator">.</span> <span class="token variable">$event</span><span class="token operator">-></span><span class="token property">name</span> <span class="token operator">.</span> <span class="token string single-quoted-string">' for class: '</span> <span class="token operator">.</span> <span class="token function">get_class</span><span class="token punctuation">(</span><span class="token variable">$event</span><span class="token operator">-></span><span class="token property">sender</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>这允许您使用以下代码通过单个处理程序捕获所有应用程序事件：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">yii<span class="token punctuation">\</span>base<span class="token punctuation">\</span>Event</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Yii</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'*'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'*'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token comment">// 触发任何类的任何事件</span></span>
<span class="line">    <span class="token class-name static-context">Yii</span><span class="token operator">::</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'trigger event: '</span> <span class="token operator">.</span> <span class="token variable">$event</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>Note: 事件处理程序设置的使用通配符可能会降低应用程序的性能。如果可能，最好避免。</p>
</blockquote>
<p>为了移除由通配符模式指定的事件处理程序，您应该在 [[yii\base\Component::off()]] 或 [[yii\base\Event::off()]] 调用中重复相同的模式。请记住，在移除事件处理程序期间传递通配符将移除为此通配符指定的处理程序，而为常规事件名称附加的处理程序将保留，即使它们与模式匹配。例如：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Yii</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$foo</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 附加常规处理</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'event.hello'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">echo</span> <span class="token string single-quoted-string">'direct-handler'</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 附加通配符处理程序</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'*'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">echo</span> <span class="token string single-quoted-string">'wildcard-handler'</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token comment">// 仅移除通配符处理程序！</span></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">off</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'*'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$foo</span><span class="token operator">-></span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'event.hello'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 输出：'direct-handler'</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>💖喜欢本文档的，欢迎点赞、收藏、留言或转发，谢谢支持！<br>
作者邮箱：zhuzixian520@126.com，github地址：<a href="https://github.com/zhuzixian520" target="_blank" rel="noopener noreferrer">github.com/zhuzixian520</a></p>
</blockquote>
</div></template>


